# $Id: console.py 9227e81e919a 2012/08/27 15:49:57 pgurumur $
# Copyright (c) 2009 Prabhu Gurumurthy  <pgurumur@gmail.com>
# 
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

__version__  = "$Revision: 9227e81e919a $"
__author__   = "$Author: pgurumur $"
__modified__ = "$Date: 2012-08-27 15:49:57Z $"

# essential imports
import atexit
import code
import os
import readline

# Completer class, for completing the commands
class CmdCompleter(object):
   def __init__ (self, Options):
      self._options = Options
      self._candidates = []

   # completer function, completes based on the dictionary provided in the
   # options
   # Refer: http://blog.doughellmann.com/2008/11/pymotw-readline.html
   def complete(self, Text, State):
      response = None
      if State == 0:
         origLine = readline.get_line_buffer()
         begin = readline.get_begidx()
         end = readline.get_endidx()
         completed = origLine[begin:end]
         words = origLine.split()

         if not words:
            self._candidates = sorted(self._options.keys())
         else:
            candidates = None
            try:
               if begin == 0:
                  candidates = self._options.keys()
               else:
                  first = words[0]
                  candidates = self._options[first]

               if completed:
                  self._candidates = [ wrd for wrd in candidates
                        if wrd.startswith(completed) ]
               else:
                  self._candidates = candidates
            except (KeyError, IndexError), err:
               self._candidates = []

      try:
         response = self._candidates[State]
      except IndexError, err:
         response = None

      return response

# Dictionary cmd line class, using code module
class CmdLine(code.InteractiveConsole):
   def __init__(self, Completer = None, locals = None, filename = "<console>",
         histfile = None):

      if not histfile:
         os.path.expanduser("~/.cmdhistory")
      # Init the parent class
      # print dir(self)
      # super(self.__class__, self).__init__()

      # What is my history file
      self._histFile = None

      # If completer is given use it before parse_and_bind is called
      if Completer:
         readline.set_completer(Completer.complete)

      # History file
      if histfile:
         self._histFile = histfile

      # Init my history
      self._initHistory()

   def _initHistory(self):
      readline.parse_and_bind("tab: complete")
      if hasattr(readline, "read_history_file"):
         try:
            if self._histFile:
               readline.read_history_file(self._histFile)
         except IOError:
            pass

         # Register the save history function, which will be called, before
         # readline exits
         atexit.register(self._saveHistory)

   def _saveHistory(self):
      # Save history to history file
      if self._histFile:
         readline.write_history_file(self._histFile)

   def GetHistLength(self):
      # Returns the current history buffer length
      return readline.get_current_history_length()

